using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using xna_game_engine.source;

namespace xna_game_engine
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class GameName : Microsoft.Xna.Framework.Game
    {
        const short WindowHeight = 1024;
        const short WindowWidth = 768;

        public GameName()
        {
            Content.RootDirectory = "Content";
            // Debug only
            Console.ForegroundColor = ConsoleColor.DarkGreen;

            // Init game systems
            GameSystems.Audio = new AudioSystem(this);
            GameSystems.Input = new InputSystem(this);
            GameSystems.Graphics = new GraphicsSystem(this, "Exodus", WindowHeight, WindowWidth);
            //GameSystems.Spells = new SpellSystem(this);
            //GameSystems.Particles = new ParticleSystem(this);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            GameSystems.Audio.Initialize();
            GameSystems.Input.Initialize();
            GameSystems.Graphics.Initialize();
            //GameSystems.Spells.Initialize();
            //GameSystems.Particles.Initialize();
            //GameGlobals.MessageBox.Initialize();
            //GameGlobals.LevelManager.Initialize();
            
            //foreach (Enemy ene in GameGlobals.EnemyList)
            //{
            //    ene.Initialize();
            //}

            base.Initialize();

        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            Console.WriteLine("Loading Assets...");
            // TODO: use this.Content to load your game content here
            GameGlobals.Content = Content;
            GameGlobals.Init();
            //GameGlobals.MessageBox.AddEntry("Welcome to Project Exodus!");
            //GameSystems.Particles.LoadContent(Content);
            GameGlobals.LevelManager.LoadContent();
            //GameGlobals.MessageBox.LoadContent();
            GameGlobals.CombatText.LoadContent();

            // Fix this later
            Console.WriteLine("...Done Loading.");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Hack for level test
            //this.Exit();
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                //this.Exit();
            }

            GameSystems.Input.PollInputDevices();
            if (GameSystems.Input.CheckKeyPress(Keys.Escape))
            {
                this.Exit();
            }
            GameGlobals.StateMachine.Update(gameTime);
            GameGlobals.EventManager.Update(gameTime);
            GameSystems.Audio.Update(gameTime);

            GameSystems.Input.Update(gameTime);
            // Update parent
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            // TODO: Add your drawing code here
            GameSystems.Graphics.ClearScreenToColor(Color.Black);
            GameSystems.Graphics.BeginSprites();
                //GameGlobals.LevelManager.Draw();
                //foreach (Enemy ene in GameGlobals.EnemyList)
                //{
                    //ene.Draw();
                //}
                //Warrior.Draw();
                GameGlobals.StateMachine.Draw();
                //GameGlobals.MessageBox.Draw();
                //GameGlobals.CombatText.Draw();
                //GameSystems.Particles.Draw();
                //GameSystems.Graphics.DrawImage(cursor, cursorPos, Color.White);
            GameSystems.Graphics.EndSprites();
            base.Draw(gameTime);
        }
    }
}
